#include "log.hpp"
//#include "UdpServer.hpp"
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <strings.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;


// pthread_mutex_t plock=PTHREAD_MUTEX_INITIALIZER;
// pthread_cond_t

log lg1;


enum
{
    SOCKET_ERR = 1,
    BIND_ERR,
};

struct ThreadDate
{
    sockaddr_in _server;
    int _sockfd;
    std::string _serverip;
};

void Useag(char *argv)
{
    cout << "you should input like this:" << argv << " a.b.c.d(Ip)" << " xxxx(port)" << endl;
}

void *Received(void *Args)
{
    ThreadDate *Td = static_cast<ThreadDate *>(Args);
    char inbuffer[1024];

    while (1)
    {
        memset(inbuffer, 0, sizeof(inbuffer));

        struct sockaddr_in temp;
        socklen_t len=sizeof(temp);

        ssize_t s = recvfrom(Td->_sockfd,inbuffer,1023,0,(sockaddr*)&temp,&len);
        
        if (s == -1)
        {

            lg1(Waring, "Recvfrom Error ", "Errno %d", "Errno string is %s", errno, strerror(errno));
            continue;
        }
        if(s>0)
        {

            inbuffer[s]=0;
            cerr<<inbuffer<<endl;
        }
        
    }
    return nullptr;
}

void *Send(void *Args)
{
    ThreadDate *Td = static_cast<ThreadDate *>(Args);
    string messages;
    while (1)
    {

        cout << "Please Enter Message@ ";
        getline(cin, messages);

        ssize_t s = sendto(Td->_sockfd, messages.data(), messages.size(), 0,
                           (sockaddr *)&(Td->_server), sizeof(Td->_server));
        if (s == -1)
        {
            lg1(Waring, "Sento Error ", "Errno %d", "Errno string is %s", errno, strerror(errno));
            continue;
        }
        usleep(200000);
    }
    return nullptr;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Useag(argv[0]);
        exit(0);
    }
    string ServerIp = argv[1];
    uint16_t ServerPort = stoi(argv[2]);

    // sockaddr_in Server;
    ThreadDate Td;
    bzero(&Td._server, sizeof(Td._server));
    Td._server.sin_family = AF_INET;
    Td._server.sin_addr.s_addr = inet_addr(ServerIp.c_str());
    Td._server.sin_port = htons(ServerPort);
    Td._serverip = ServerIp;
    Td._sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (Td._sockfd < 0)
    {
        lg1(Fatel, "socket create faile , sockfd is %d", Td._sockfd);
        exit(SOCKET_ERR);
    }

    pthread_t recvr, sender;

    pthread_create(&recvr, nullptr, Received, &Td);
    pthread_create(&sender, nullptr, Send, &Td);

    pthread_join(recvr, nullptr);
    pthread_join(sender, nullptr);

    close(Td._sockfd);
    //pthread_mutex_destroy(&plock);
    return 0;
}